using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using System.Collections;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.WebPartPages.Communication;

namespace PhilWicklund.com.ListItemArchiver
{
	/// <summary>
	/// Description for ListItemArchiver.
	/// </summary>
	[DefaultProperty("Text"),
		ToolboxData("<{0}:ListItemArchiverWP runat=server></{0}:ListItemArchiverWP>"),
		XmlRoot(Namespace = "PhilWicklund.com.ListItemArchiver")]
	public class ListItemArchiverWP : Microsoft.SharePoint.WebPartPages.WebPart, ICellProvider
	{
		private const string defaultText = "";
		
		#region Properties
		private string listName = "";

		[Browsable(false),
		Category("List Properties"),
		DefaultValue(defaultText),
		Description("hidden."),
		FriendlyName("List Name"),
		ReadOnly(false),
		WebPartStorage(Storage.Personal)
		]
		public string ListName
		{
			get{return listName;}
			set{listName = value;}
		}

		public override ToolPart[] GetToolParts()
		{
			try
			{
				//Number of toolparts to display
				ToolPart[] toolparts = new ToolPart[3];
				
				ListItemArchiverTP liatp = new ListItemArchiverTP(ListName);
				toolparts[0] = liatp;

				CustomPropertyToolPart cptp = new CustomPropertyToolPart();
				toolparts[1] = cptp;

				WebPartToolPart wptp = new WebPartToolPart();
				toolparts[2] = wptp;

				return toolparts;
			}
			catch
			{
				return base.GetToolParts ();
			}
		}
		#endregion
		
		/// <summary>
		/// Render this Web Part to the output parameter specified.
		/// </summary>
		/// <param name="output"> The HTML writer to write out to </param>
		protected override void RenderWebPart(HtmlTextWriter output)
		{
			try 
			{
				EnsureChildControls();
				// If a connection to another part has been made
				if (_cellConnectedCount > 0)
				{
					RenderChildren(output);
				}
				else
				{
					//There wasn't a cell connection formed,
					//so just output a message
					output.Write("NO CELL INTERFACE CONNECTION");
				}
			}
			catch (Exception e) {output.WriteLine("Exception Occured -->> " + e);}
		}

		#region Connection Interfaces
		//Declare Connection Events
		public event CellProviderInitEventHandler CellProviderInit;
		public event CellReadyEventHandler CellReady;


		//Keep a count of ICell connections
		private int _cellConnectedCount = 0;

		//Web Part UI
		private DateTime date;
		
		//Cell information
		private string _cellName;
		private string _cellDisplayName;

		//Used to keep track of whether or not the Button in the Web Part was clicked
		private bool _cellClicked = false;


		//EnsureInterfaces
		//Notification to the Web Part that is should ensure that all
		//its interfaces are registered using RegisterInterface.
		public override void EnsureInterfaces()
		{
			//Registers an interface for the Web Part
			RegisterInterface("MyCellProviderInterface_WPQ_",  //InterfaceName
				InterfaceTypes.ICellProvider,					//InterfaceType
				WebPart.UnlimitedConnections,					//MaxConnections
				ConnectionRunAt.Server,							//RunAtOptions
				this,											//InterfaceObject
				"CellProviderInterface_WPQ_",					//InterfaceClientReference
				"Provide a date to filter on",					//MenuLabel
				"Provides a date to another part to be used to archive data with");					//Description
		}


		//CanRunAt - called by framework to determine where a part can run.
		public override ConnectionRunAt CanRunAt()
		{
			//This Web Part can run on both the client and the server
			return ConnectionRunAt.Server;
		}

		//PartCommunicationConnect - Notification to the Web Part that it has been connected.
		public override void PartCommunicationConnect(
			string interfaceName,
			WebPart connectedPart,
			string connectedInterfaceName,
			ConnectionRunAt runAt)
		{
			
			//Must be a server-side part so need to create the Web Part's controls
			EnsureChildControls(); 

			//Check if this is my particular cell interface
			if (interfaceName == "MyCellProviderInterface_WPQ_")
			{
				//Keep a count of the connections
				_cellConnectedCount++;
			}
		}

		//PartCommunicationInit - Broadcast schema information regarding what this webpart is sending to the receiving webpart
		public override void PartCommunicationInit()
		{
			//If the connection wasn't actually formed then don't want to send Init event
			if(_cellConnectedCount > 0)
			{
				//If there is a listener, send Init event
				if (CellProviderInit != null)
				{
					//Need to create the args for the CellProviderInit event
					CellProviderInitEventArgs cellProviderInitArgs = new CellProviderInitEventArgs();
					
					//Set the FieldName
					cellProviderInitArgs.FieldName = _cellName;
					cellProviderInitArgs.FieldDisplayName = _cellDisplayName;
					
					//Fire the CellProviderInit event.
					CellProviderInit(this, cellProviderInitArgs);
				}
			}
		}
		
		public void CellConsumerInit(object sender, CellConsumerInitEventArgs cellConsumerInitArgs)
		{
			//This is where the Provider part could see what type of "Cell" the Consumer
			//was expecting/requesting.
			//For this simple code example, this information is not used anywhere.
		}

		//PartCommunicationMain - Called by the framework to allow part to fire any remaining events
		public override void PartCommunicationMain()
		{
			//If the connection wasn't actually formed then don't want to send Ready event
			if(_cellConnectedCount > 0)
			{
				//If there is a listener, send CellReady event
				if (CellReady != null)
				{
					//Need to create the args for the CellProviderInit event
					CellReadyEventArgs cellReadyArgs = new CellReadyEventArgs();

					//If user clicked button then send the value
					if (_cellClicked)
					{
						//Set the Cell to the value of the TextBox text
						//This is the value that will be sent to the Consumer
						cellReadyArgs.Cell = ListName + ":" + date.ToShortDateString();
					}
					else
					{
						//The user didn't actually click the button
						//so just send an empty string to the Consumer
						cellReadyArgs.Cell = "";
					}

					
					//Fire the CellReady event.
					//The Consumer will then receive the Cell value
					CellReady(this, cellReadyArgs);
				}
			}
		}
		// <param name="sender">The Button object</param>
		// <param name="e">The Event Arguments</param>
		private void FilterClicked(object sender, EventArgs e)
		{
			LinkButton b = (LinkButton)sender;
			string space = " ";
			string [] dateClicked = b.Text.Split(space.ToCharArray());
			date = new DateTime(int.Parse(dateClicked[1]),MonthStringConverter.getMonthInt(dateClicked[0]),1);
			_cellClicked = true; //user clicked button, set to true
		}
		#endregion

		protected override void CreateChildControls()
		{
			if (ListName != "") 
			{
				try 
				{
					this.Controls.Add(new LiteralControl("<table>"));			
					SPWeb web = SPControl.GetContextWeb(Context);
					SPList list = web.Lists[ListName];
				
					ArrayList itemsBackwards = new ArrayList();
					foreach (SPListItem item in list.Items)
					{
						itemsBackwards.Add(item);
					}
					itemsBackwards.Reverse();
				
					foreach (SPListItem item in itemsBackwards) 
					{
						string created = item["Created"].ToString();
						string year = created.Substring(created.LastIndexOf("/")+1, 4);
						string month = created.Substring(0, 2);
						month = month.Replace("/", "");
					
						bool controlFound = false;
						foreach (Control control in this.Controls)
						{
							// Only create a link once for a given month
							if (control.ID == month.ToString() + year.ToString())
							{	
								controlFound = true;
								break;
							}
						}
						// If the link for this month is not already created,
						// created a new link
						if (controlFound == false) 
						{
						
							LinkButton button = new LinkButton();
							button.Text = MonthStringConverter.getMonthString(int.Parse(month)) + " " + year;
							button.ID = month.ToString() + year.ToString();
							button.Click += new EventHandler(FilterClicked);
							this.Controls.Add(new LiteralControl("<tr><td><span style='vertical-align=middle'><img src='/_layouts/images/bullet.gif' border=0 /></span></td><td>"));
							this.Controls.Add(button);
							this.Controls.Add(new LiteralControl("</td></tr>"));
						}
					
					}

					//Set the Cell information.
					//This information will be passed to the Consumer by
					//firing the CellProviderInit event.
					_cellName = "Date";
					_cellDisplayName = "Date";
	
					_cellClicked = false; // Initialize to false -- user hasn't clicked yet
					this.Controls.Add(new LiteralControl("</table>"));
				}
				catch (Exception e) {Controls.Add(new LiteralControl(e.ToString()));}
			}
			else
			{
				string url = "javascript:MSOTlPn_ShowToolPaneWrapper(\"1\",\"129\",\"" + this.ID + "\")";
				this.Controls.Add(new LiteralControl("List has not yet been specified, <a href='"+url+"'>open the tool pane</a> to select the desired list to archive."));
			}
		}
	}
}